package app.auto.runner.base.data;

import android.text.TextUtils;


import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import app.auto.AndroidInstance;
import app.auto.runner.base.intf.FunCallback;
import app.auto.runner.base.intf.ListBuilder;
import app.auto.runner.base.intf.MapBuilder;

public class ExtractUtil<T> extends AndroidInstance {


    private String equalfield;
    private String equalfieldvalue;
    private FunCallback funcallback;

    public ExtractUtil whereEqual(String equalfield, String value) {
        this.equalfield = equalfield;
        this.equalfieldvalue = value;
        return this;
    }

    public Map splitToMapDependsOnKey(List<Map> raw, String keyInListMap) {
        MapBuilder list = MapBuilder.build();

        for (Map m : raw) {
            if (m.get(keyInListMap) != null) {
                list.addMap(MapBuilder.build().add(m.get(keyInListMap), m).get());
            }
        }
        return list.get();

    }

    public List combineMapValueToList(Map raw) {
        return new ArrayList(raw.values());

    }


    public List filterValueDenpendonMap(List<Object> os, Class stringClass, FunCallback funCallback, Object... s) {
        return denpendonMapOrValue(os, stringClass, funCallback, Arrays.asList(s).<String>toArray(new String[s.length]));
    }


    public List<T> denpendonMapOrValue(List<Object> os, Class stringClass, FunCallback funCallback, String... s) {
        List<T> rs = new ArrayList<T>();
        try {
            Set values = new TreeSet();
            for (Object o : os) {
                Object v = null;
//                if (o instanceof BaiduNetUtil.EntityObj) {
//                    Map m = ((Map) ((BaiduNetUtil.EntityObj) o).getMap());
//                    for (Object k : m.keySet()) {
//                        v = m.get(k);
//                        if (TextUtils.isEmpty((CharSequence) v)) {
//                            continue;
//                        }
//                    }
//                    rs.add((T) v);
//                } else
                if (o instanceof Map) {
                    Map m = ((Map) o);
                    List l = s == null ? null : Arrays.asList(s);
                    for (Object k : m.keySet()) {
                        if (l == null || l.size() == 0 || l.contains(k)) {

                            v = m.get(k);
//                            if (l.size() > 1) {
//                                if (TextUtils.isEmpty(v.toString())) {
//                                    continue;
//                                }
//                            }
                            if (!TextUtils.isEmpty(equalfield) && !TextUtils.isEmpty(equalfieldvalue)) {
                                if (m.containsKey(equalfield)) {
                                    if (m.get(equalfield).equals(equalfieldvalue)) {
                                        if (values.contains(v)) {
                                            break;
                                        } else {
                                            values.add(v);
                                        }
                                    } else {
                                        break;
                                    }
                                }
                            } else {
                                if (values.contains(v)) {
                                    break;
                                } else {
                                    values.add(v);
                                }
                            }
                            if (stringClass == Map.class) {
                                Object rv = v;
                                if (funCallback != null) {
                                    rv = funCallback.onResult(rv, null);
                                }
                                if (m.containsKey(k)) {
                                    m.put(k, rv);
                                }
                                rs.add((T) m);
                                break;
                            } else {
                                Object rv = v;
                                if (funCallback != null) {
                                    rv = funCallback.onResult(rv, null);
                                }
                                rs.add((T) rv);
                                break;

                            }

                        } else {
                            continue;
                        }
                    }

                } else {

                    for (Object k : s) {

                        if (TextUtils.isEmpty((CharSequence) k)) {
                            continue;
                        }
                        Field f = null;
                        try {
                            f = o.getClass().getDeclaredField(k.toString());
                        } catch (Exception e) {
                            f = o.getClass().getField(k.toString());
                        }

                        f.setAccessible(true);
                        Object rv = f.get(o);
                        if (funCallback != null) {
                            rv = funCallback.onResult(rv, null);
                        }
                        rs.add((T) rv);
                    }
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rs;
    }

    //bug propabaly
    public List<T> outputList(List<Object> os, String... s) {
        List<T> rs = new ArrayList<T>();
        try {
            Set values = new TreeSet();
            for (Object o : os) {
                Object v = null;
//                if (o instanceof BaiduNetUtil.EntityObj) {
//                    Map m = ((Map) ((BaiduNetUtil.EntityObj) o).getMap());
//                    for (Object k : m.keySet()) {
//                        v = m.get(k);
//                        if (TextUtils.isEmpty((CharSequence) v)) {
//                            continue;
//                        }
//                    }
//                    rs.add((T) v);
//                } else
                if (o instanceof Map) {
                    Map m = ((Map) o);
                    List l = s == null ? null : Arrays.asList(s);
                    for (Object k : m.keySet()) {
                        if (l == null || l.size() == 0 || l.contains(k)) {

                            v = m.get(k);
                            if (l.size() > 1) {
                                if (TextUtils.isEmpty(v.toString())) {
                                    continue;
                                }
                            }
                            if (!TextUtils.isEmpty(equalfield) && !TextUtils.isEmpty(equalfieldvalue)) {
                                if (m.containsKey(equalfield)) {
                                    if (m.get(equalfield).equals(equalfieldvalue)) {

                                    } else {
                                        break;
                                    }
                                }
                            } else {
                                if (values.contains(v)) {
                                    break;
                                } else {
                                    values.add(v);
                                }
                            }
                            rs.add((T) m);
                            break;

                        } else {
                            continue;
                        }
                    }

                } else {

                    for (String k : s) {

                        if (TextUtils.isEmpty((CharSequence) k)) {
                            continue;
                        }
                        Field f = null;
                        try {
                            f = o.getClass().getDeclaredField(k);
                        } catch (Exception e) {
                            f = o.getClass().getField(k);
                        }

                        f.setAccessible(true);

                        Object rv = f.get(o);
                        if (funcallback != null) {
                            rv = funcallback.onResult(rv, null);
                        }
                        rs.add((T) rv);
                    }
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rs;
    }


    @Override
    public AndroidInstance use(Object mp, Object... p) {
        return null;
    }

    public List combine(List... ls) {
        List list = new ArrayList();
        for (int j = 0; j < ls.length; j++) {
            String item = "";
            for (int i = 0; i < ls[j].size(); i++) {
                if (!(j < ls.length && i < ls[j].size())) {
                    item += "";
                } else {
                    item += "&&" + ls[j].get(i).toString();
                }
            }
            if (TextUtils.isEmpty(item)) {
                item = "";
            } else
                item = item.substring(2);
            list.add(item);
        }
        return list;
    }

    public List combineCsv(List... ls) {
        List list = new ArrayList();
        for (int i = 0; i < ls[0].size(); i++) {
            String item = "";
            for (int j = 0; j < ls.length; j++) {

                if (!(j < ls.length && i < ls[j].size())) {
                    item += "";
                } else {
                    item += "," + ls[j].get(i).toString();
                }
            }
            if (TextUtils.isEmpty(item)) {
                item = "";
            } else
                item = item.substring(1);
            list.add(item);
        }
        return list;
    }

    public void combine(List<Map> os, String nameput, Map inject, String submit_field) {
        for (int index = 0; index < os.size(); index++) {
            Map m = os.get(index);
            Object val;
            if (TextUtils.isEmpty(submit_field)) {
                val =
                        inject.get(nameput);
            } else {
                val = inject.get(m.get(submit_field));
            }
            val = val == null || val.equals("null") ? "" : val;
            m.put(nameput, val);
        }
    }
}
